/*
 * writer.cpp
 *
 *  Created on: 22/07/2014
 *      Author: nicolas
 */

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include "../../ipc/Socket.h"
#include "../../defines.h"
#include <string>
#include <sstream>

using namespace std;

#define DESTINATARIO 401

void signalMsg(int numero, Socket& sock) {
	MENSAJE_BROKER msg;
	msg.destinatario = DESTINATARIO;
	msg.origen = 3;
	msg.tipo = TIPO_SEM_SIGNAL;
	msg.idSem = numero;
	sock.send(&msg, sizeof(MENSAJE_BROKER));

}

void waitMsg(int numero, Socket& sock) {
	MENSAJE_BROKER msg;
	msg.destinatario = DESTINATARIO;
	msg.origen = 3;
	msg.tipo = TIPO_SEM_WAIT;
	msg.idSem = numero;
	sock.send(&msg, sizeof(MENSAJE_BROKER));
}

void salaIOCantPers(Tipos::LugarDeSala lugar, int numeroSala,
		int valorAescribir, Socket& sock) {
	MENSAJE_BROKER msg;
	msg.destinatario = DESTINATARIO;
	msg.origen = 3;
	if (valorAescribir == -1) {
		msg.tipo = TIPO_SALA_LEER_CANTPERSONAS;
	} else {
		msg.tipo = TIPO_SALA_ESCRIBIR_CANTPERSONAS;
		msg.valorAEscribir = valorAescribir;
	}
	msg.lugarSala = lugar;
	msg.numSala = numeroSala;
	sock.send(&msg, sizeof(MENSAJE_BROKER));
}

void salaIOReservas(Tipos::LugarDeSala lugar, int numeroSala,
		int valorAescribir, Socket& sock) {
	MENSAJE_BROKER msg;
	msg.destinatario = DESTINATARIO;
	msg.origen = 3;
	if (valorAescribir == -1) {
		msg.tipo = TIPO_SALA_LEER_RESERVAS;
	} else {
		msg.tipo = TIPO_SALA_ESCRIBIR_RESERVAS;
		msg.valorAEscribir = valorAescribir;
	}
	msg.lugarSala = lugar;
	msg.numSala = numeroSala;
	sock.send(&msg, sizeof(MENSAJE_BROKER));
}

void salaIOPersonas(Tipos::LugarDeSala lugar, int numeroSala, int numPersona,
		int valorAescribir, Socket& sock) {
	MENSAJE_BROKER msg;
	msg.destinatario = DESTINATARIO;
	msg.origen = 3;
	if (valorAescribir == -1) {
		msg.tipo = TIPO_SALA_LEER_PERSONAS;
	} else {
		msg.tipo = TIPO_SALA_ESCRIBIR_PERSONAS;
		msg.valorAEscribir = valorAescribir;
	}
	msg.numPersona = numPersona;
	msg.lugarSala = lugar;
	msg.numSala = numeroSala;
	sock.send(&msg, sizeof(MENSAJE_BROKER));
}

void salaIOEstadoBus(Tipos::LugarDeSala lugar, int numeroSala,
		int valorAescribir, Socket& sock) {
	MENSAJE_BROKER msg;
	msg.destinatario = DESTINATARIO;
	msg.origen = 3;
	if (valorAescribir == -1) {
		msg.tipo = TIPO_SALA_LEER_ESTADOBUS;
	} else {
		msg.tipo = TIPO_SALA_ESCRIBIR_ESTADOBUS;
		msg.valorAEscribir = valorAescribir;
	}
	msg.lugarSala = lugar;
	msg.numSala = numeroSala;
	sock.send(&msg, sizeof(MENSAJE_BROKER));
}

int main(int argc, char **argv) {

	cout << "Help:" << endl;
	cout << "Semaforos: arg0 = idSem" << endl;
	cout << "s : signal" << endl;
	cout << "w : wait" << endl;
	cout << "Lectura Sala: arg0 = lugar, arg1 = numero" << endl;
	cout << "slc : sala leer cantidad personas" << endl;
	cout << "slr : sala leer reservas" << endl;
	cout << "slp : sala leer personas" << endl;
	cout << "sle : sala leer estado bus" << endl;
	cout << "Escritura Sala: arg0 = lugar, arg1 = numero, arg2 = valor a escribir" << endl;
	cout << "sec : sala escribir cantidad personas" << endl;
	cout << "ser : sala escribir reservas" << endl;
	cout << "sep : sala escribir personas" << endl;
	cout << "see : sala escribir estado bus" << endl;

	Socket sock;
	int puerto = 5555;
	MENSAJE_BROKER msg;
	msg.esReceptor = true; // la direccion de la comunicacion es cliente -> broker
	msg.id = 3;

	sock.connectTo("localhost", puerto);
	sock.send(&msg, sizeof(MENSAJE_BROKER)); // fin del handshake

	bool salir = false;
	string line;
	string delimiter = " ";
	while ((getline(cin, line)) && !salir) {
		string command = line.substr(0, line.find(delimiter));
		line.erase(0, line.find(delimiter) + delimiter.length());
		if (command == "s") {
			string arg0 = line.substr(0, line.find(delimiter));
			signalMsg(atoi(arg0.c_str()), sock);
		} else if (command == "w") {
			string arg0 = line.substr(0, line.find(delimiter));
			waitMsg(atoi(arg0.c_str()), sock);
		} else if (command == "slc") {
			string arg0 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg1 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			salaIOCantPers((Tipos::LugarDeSala) atoi(arg0.c_str()),
					atoi(arg1.c_str()), -1, sock);
		} else if (command == "slr") {
			string arg0 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg1 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			salaIOReservas((Tipos::LugarDeSala) atoi(arg0.c_str()),
					atoi(arg1.c_str()), -1, sock);
		} else if (command == "slp") {

		} else if (command == "sle") {
			string arg0 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg1 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			salaIOEstadoBus((Tipos::LugarDeSala) atoi(arg0.c_str()),
					atoi(arg1.c_str()), -1, sock);
		} else if (command == "sec") {
			string arg0 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg1 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg2 = line.substr(0, line.find(delimiter));
			salaIOCantPers((Tipos::LugarDeSala) atoi(arg0.c_str()),
					atoi(arg1.c_str()), atoi(arg2.c_str()), sock);

		} else if (command == "ser") {
			string arg0 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg1 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg2 = line.substr(0, line.find(delimiter));
			salaIOReservas((Tipos::LugarDeSala) atoi(arg0.c_str()),
					atoi(arg1.c_str()), atoi(arg2.c_str()), sock);
		} else if (command == "sep") {

		} else if (command == "see") {
			string arg0 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg1 = line.substr(0, line.find(delimiter));
			line.erase(0, line.find(delimiter) + delimiter.length());
			string arg2 = line.substr(0, line.find(delimiter));
			salaIOEstadoBus((Tipos::LugarDeSala) atoi(arg0.c_str()),
					atoi(arg1.c_str()), atoi(arg2.c_str()), sock);

		} else if (command == "q") {
			salir = true;
			msg.tipo = TIPO_FINALIZAR;
			msg.destinatario = 3;
			msg.origen = 3;
			sock.send(&msg, sizeof(MENSAJE_BROKER));
		} else {
			cout << "Parametro desconocido" << endl;
		}
	}

	sock.closeSock();
}

